package com.cty.service.impl;

import com.cty.Dao.StudentDao;
import com.cty.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

@Transactional//声明式事务的注解(再方法上目的：在方法中加入事务，类上：在整个类的方法上加入事务)
@Service
public class StudentServiceImpl implements StudentService {


    /*
    *
    * 1.只读模式
    *   只读模式的开关：boolean readOnly() default false;
    *   只读模式:可以提高查询的效率
    *   但是查询模式本身就不需要事务
    *   这个开关的作用:一般开启事务都是在类上开启，
    *   导致所有的方法都开启了事务，而查询方法不需要，
    *   在查询方法中关闭即可
    *
    * 2.事务的超时时间设置
    *   timeout = 数字（秒数） 默认-1 永不超时  当程序超出设置的时间，就会超时回滚，释放资源
    *   TransactionTimedOutException会报这个异常到时候捕捉这个异常即可
    *   如果在类上设置超时时间就不要在方法上加注解，会被覆盖掉
    * 3.控制回滚异常的种类
    *   默认：是回滚运行时异常，而io异常不会滚
    *   在注解中加入rollbackFor指定回滚的异常.class,
    *   在注解中加入noRollbackFor指定在回滚的异常中指定不回滚的异常
    * 4.隔离级别的设置
    *   在注解中加入isolation设置隔离级别
    *   推荐使用第二种隔离级别(根据你使用的具体数据库类型设置)
    * 5.事务的传播行为：在一个事务方法中调用另一个事务方法的行为
    *   默认值propagation = Propagation.REQUIRED：两个事务会被统一为一个事务
    *   注意：spring底层会被代理两个事务必须不属于一个类
    *   另一个常用值：propagation = Propagation.REQUIRES_NEW：将两个事务独立成两个事务互不干扰
    *
    * */




    @Autowired
    private StudentDao studentDao;


    @Override
    @Transactional(rollbackFor = Exception.class,noRollbackFor = FileNotFoundException.class,
    isolation = Isolation.READ_COMMITTED)
    public void update() throws FileNotFoundException {
        studentDao.updateNameById("nihao",1);
        new FileInputStream("xxx");
        System.out.println("---------");
        studentDao.updateAgeById(100,1);
    }

    @Transactional(readOnly = true)
    public void queryAll() {

    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void changeAge(){
        studentDao.updateAgeById(99,1);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void changeName() {
        studentDao.updateNameById("test2",1);
        int i = 1/0;
    }

}
